<?php
/**
 * @name /lib/public/DB.php
 * @author Michael Foss <mfoss@clarionsafety.com>
 * @version 2007.10.19
 * 
 * Library for MySQL database connectivity.
 * IMPORTANT: Any versions less than 2007.08.30 should be
 * upgraded immediately, as there are critical bugs in the
 * DB constructor and the QueryKeyVal function!
 */

ini_set('short_open_tag', 'On');

/**
 * Database class.
 *
 */
class DB {
  /**
   * Database username.
   *
   * @var string
   */
  var $Username;
  /**
   * Database password.
   *
   * @var string
   */
  var $Password;
  /**
   * Database server address.
   *
   * @var string
   */
  var $Server;
  /**
   * Database name.
   *
   * @var string
   */
  var $Database;
  
  /**
   * Constructor; automatically connects to database; if $username is an array,
   * connects via $username['USER', 'PASS', 'HOST', 'NAME']; if nothing is passed
   * in, connects via $GLOBALS['dbInfo']['USER', 'PASS', 'HOST', 'NAME']; if all
   * parameters are passed in, connects normally using parameters as strings;
   * stores connection in $GLOBALS['DB_CONNECTIONS'][$server]; die()s with error
   * message on invalid connection.
   *
   * @param string | string[] $username
   * @param string $password
   * @param string $server
   * @param string $database
   * @return DB
   */
  function DB($username = '', $password = '', $server = '', $database = '') {
    if (is_array($username))
      $result = $this->connect($username['USER'], $username['PASS'], $username['HOST'], $username['NAME']);
    elseif (!$username && !$password && !$server && !$database)
      $result = $this->connect($GLOBALS['dbInfo']['USER'], $GLOBALS['dbInfo']['PASS'], $GLOBALS['dbInfo']['HOST'], $GLOBALS['dbInfo']['NAME']);
    elseif ($server)
      $result = $this->connect($username, $password, $server, $database);
    if (!$result)
      die(mysql_error());
  }

  /**
   * Returns the result set from a query.
   *
   * @param SQL $q
   * @return mixed[][]
   */
  function Query($q) {
    if (!$GLOBALS['DB_CONNECTIONS'][$this->Server])
      return false;

    // Execute queries
    $result = @mysql_query($q, $GLOBALS['DB_CONNECTIONS'][$this->Server]);

    // Get resulting 2D array
    if ($result) {
      while ($arr = @mysql_fetch_array($result))
        if (is_array($arr))
          $report[] = $arr;

      // Free result
      if (is_resource($result)) {
        mysql_free_result($result);
        return $report;
      }

      return $result;
    }
    return false;
  }
 
  /**
   * Connects to a server and selects a specific database; returns true on a valid
   * connection, false on failure.
   *
   * @param string $username
   * @param string $password
   * @param string $server
   * @param string $database
   * @return boolean
   */
  function connect($username, $password, $server, $database) {
    $server = strtolower($server);
    if (!is_resource($GLOBALS['DB_CONNECTIONS'][$server]))
      $GLOBALS['DB_CONNECTIONS'][$server] = @mysql_connect($server, $username, $password);
    if (!$GLOBALS['DB_CONNECTIONS'][$server])
      return false;

    // Connect to database
    if (!@mysql_select_db($database))
      return false;
  
    $this->Username = $username;
    $this->Password = $password;
    $this->Server = $server;
    $this->Database = $database;
    return true;
  }
 
  /**
   * Disconnects from the server.
   *
   */
  function disconnect() {
    if (@mysql_close($GLOBALS['DB_CONNECTIONS'][$this->Server])) {
      $GLOBALS['DB_CONNECTIONS'][$this->Server] = false;
      $this->Username = '';
      $this->Password = '';
      $this->Server = '';
      $this->Database = '';
    }
  }
  
  /**
   * Queries the database, returning a 2-dimensional array of data.
   *
   * @param SQL $query
   * @return scalar[][]
   */
  function QueryArr($query) {
    if (!$GLOBALS['DB_CONNECTIONS'][$this->Server])
      return false;

    if (is_array($query))
      for ($i = 0; $i < count($query); $i++)
        $report = $this->Query($query[$i]);
    else
      $report = $this->Query($query);
    
    return $report;
  }

  /**
   * Queries the database, returning a 1-dimensional array of data; will only
   * return the first row if multiple rowsets returned from query.
   *
   * @param SQL $query
   * @return scalar[]
   */
  function QueryRow($query) {
    if (!$GLOBALS['DB_CONNECTIONS'][$this->Server])
      return false;

    $report = $this->QueryArr($query);

    if (is_array($report))
      return $report[0];
    else
      return false;
  }

  /**
   * Queries the database, returning a 1-dimensional array of data; will only
   * return the first column if multiple columns returned from query.
   *
   * @param SQL $query
   * @return scalar[]
   */
  function QueryCol($query) {
    if (!$GLOBALS['DB_CONNECTIONS'][$this->Server])
      return false;

    $report = $this->QueryArr($query);
    if (!$report)
      return false;
    foreach ($report as $key => $val)
      $colreport[$key] = $val[0];
    return $colreport;
  }

  /**
   * Queries the database, returning a scalar; will only return the first row
   * and column if multiple rowsets and/or columns returned from query.
   *
   * @param SQL $query
   * @return scalar[]
   */
  function QueryVal($query) {
    if (!$GLOBALS['DB_CONNECTIONS'][$this->Server])
      return false;

    $row = $this->QueryRow($query);
    if (is_array($row))
      return $row[0];
    else
      return false;
  }

  /**
   * Returns an associative array such that the key is the first column in the
   * query resultset and the value is the second column; if $arr is supplied,
   * the results of this function are appended to this array, then returned.
   *
   * @param SQL $query
   * @param mixed[] $arr
   * @return mixed[]
   */
  function QueryKeyVal($query, $arr = false) {
    $result = $this->QueryArr($query);
    if (is_array($result))
      for ($i = 0; $i < count($result); $i++)
        $arr[$result[$i][0]] = $result[$i][1];
    return $arr;
  }
}